package interview_service

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"peilian-api/app/global/common"
	"peilian-api/app/global/databases/tables"
	"peilian-api/app/global/log"
	"peilian-api/app/global/variable"
	"peilian-api/utils/format"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

type InterviewClient struct {
	CareerId            uint
	SessionId           uint
	CurrentNum          uint
	Total               uint
	Transition          bool
	CurrentType         string
	QuestionId          uint
	AnswerText          string
	AnswerUrl           string
	SampleRules         map[int][]string // criteria
	OriginQuestion      *tables.Question
	CurrentQuestion     *tables.Question // 当前的信息
	CurrentRealQuestion *tables.RealQues
	Career              *tables.Career
	SpeakTime           uint
	PointStruct         []int      // 要点评分
	Type                string     // 当前题目类型
	StartTime           *time.Time // 记录面试开始时间
}

func GetSessionObj(id uint) (*tables.Session, error) {
	session := new(tables.Session)
	err := variable.DB.MySQL.Model(&tables.Session{}).Preload("User").Preload("Career").First(session, id).Error
	if err != nil {
		return session, err
	}
	return session, nil
}

func (c *Client) CacheInterviewClient() {
	b, _ := json.Marshal(c.Bus)
	variable.DB.Redis.Set(fmt.Sprintf(common.RedisSessionClient, c.Bus.Session.ID), string(b), 60*60*time.Second)
}

func (c *Client) GetCacheInterviewClient(ctx *gin.Context, sessionId uint) error {
	sc := variable.DB.Redis.Get(fmt.Sprintf(common.RedisSessionClient, c.Bus.Session.ID))
	s, _ := sc.Result()
	b := Business{}
	if len(s) == 0 {
		return fmt.Errorf("data is error")
	}
	_ = json.Unmarshal([]byte(s), &b)
	c.Bus = b
	return nil
}

// 初始化initCriteria
func (c *Client) InitCriteria() error {
	if c.Bus.Criteria == nil {
		var dc []tables.Career
		c.Bus.Criteria = make(map[int][]string)

		// 先获取职业的能力
		whereStr := ""
		switch c.Bus.Session.CareerID {
		case tables.QCivilServant:
			whereStr = "id = ?"
		case tables.BankTrainee:
			whereStr = fmt.Sprintf("id in (?,%d)", tables.SelfIntroduction) // 14-公共能力
		default:
			whereStr = fmt.Sprintf("id in (?,%d,%d)", tables.QCommonId, tables.SelfIntroduction)
		}
		d := variable.DB.MySQL.Model(&tables.Career{}).Where(whereStr, c.Bus.Session.CareerID).Order("id desc").Find(&dc)
		if d.Error != nil {
			return errors.New("该题库没有考察维度")
		}
		for i := 0; i < len(dc); i++ {
			var ts []string
			s := dc[i].SelectRule
			json.Unmarshal([]byte(s), &ts)
			c.Bus.Criteria[int(dc[i].ID)] = append(c.Bus.Criteria[int(dc[i].ID)], ts...)
		}
	}
	if len(c.Bus.Criteria) == 0 {
		return errors.New("该题库没有考察维度")
	}
	return nil
}

// 初始化类
func InitClient(ctx *gin.Context, sessionId uint) *Client {
	session, err := GetSessionObj(sessionId)
	if err != nil {
		return nil
	}

	var bus = Business{
		Session: session,
	}
	client := &Client{
		Id:  strconv.Itoa(int(sessionId)),
		Bus: bus,
		Ctx: ctx,
		Logger: &log.MyLogger{
			Zlog: log.InitLogger(fmt.Sprintf("logs/%d.log", session.ID)),
		},
	}
	// 获取一下缓存是否存在
	err = client.GetCacheInterviewClient(ctx, sessionId)
	if err != nil {
		if err.Error() != "data is error" {
			return nil
		}
		client.InitCriteria()
		b, _ := json.Marshal(bus.Session)
		log.Logger.InfoF(ctx, fmt.Sprintf("websocket client info: %+v, interview sessions info:%s", client, string(b)))
	}
	reportType := "web"
	if session.Career == nil {
		reportType = "custom"
	} else {
		reportType = session.Career.ReportType
	}

	switch reportType {
	case "web":
		nextRealize := &Recommend{Client: client}
		if session.CareerID == tables.QCommonId {
			nextRealize.IRecommend = &CommonCareer{}
		} else {
			nextRealize.IRecommend = &OccupationCareer{}
		}
		client.INextQuestion = nextRealize
	case "custom", "none":
		client.INextQuestion = &CustomClient{Client: client}
	case "pdf":
		client.INextQuestion = &DefaultClient{Client: client}
	default:
		format.NewResponseJson(ctx).Err(http.StatusBadRequest, "暂不支持该岗位面试")
		return nil
	}

	client.CacheInterviewClient()
	return client
}
